package nero.yncc.com.createart.utils;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import cn.finalteam.galleryfinal.model.PhotoInfo;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import static android.content.ContentValues.TAG;

/**
 * Created by nero on 2017/5/31.
 */

public class HttpUtils {
    public static final int TYPE_ARRAY = 0;
    public static final int TYPE_OBJECT = 1;
    public static final int TYPE_NOTHING = 2;

    public final static int CONNECT_TIMEOUT = 20;
    public final static int READ_TIMEOUT = 20;
    public final static int WRITE_TIMEOUT = 20;

    public static final MediaType JSON
            = MediaType.parse("application/json; charset=utf-8");


    public static void get(final Activity activity, String url, HashMap<String, String> params, final Class className, final int type, final HttpCallback callback) {

        Set<String> keyset = params.keySet();

        StringBuilder sb = new StringBuilder();
        for (String key : keyset) {
            if (!TextUtils.isEmpty(sb.toString())) {
                sb.append("&");
            }
            if (!TextUtils.isEmpty(params.get(key)))
                sb.append(key + "=" + params.get(key));
        }
        if (sb.length() > 0 && sb.toString().endsWith("&")) {
            url += "?" + sb.substring(0, sb.length() - 1);
        } else {
            url += "?" + sb.toString();
        }


        OkHttpClient client = new OkHttpClient.Builder().readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)//设置读取超时时间
                .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)//设置写的超时时间
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)//设置连接超时时间;
                .build();
        Request req = new Request.Builder().get().url(url).build();
        client.newCall(req).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        String s = e.getMessage();
                        callback.fail(s);
                    }
                });

            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                final String returnStr = response.body().string();
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //Response{protocol=http/1.1, code=200, message=OK, url=http://yxsf.ynthgy.com/server//index.php/home/user/login}
                        try {
                            JSONObject all = new JSONObject(returnStr);
                            String status = all.getString("status");
                            String message = all.getString("msg");
                            if (status.equals("1")) {
                                if (type == TYPE_ARRAY) {
                                    callback.success(message, all.getJSONArray("result"));
                                } else if (type == TYPE_NOTHING) {
                                    callback.success(message, all.getString("result"));
                                } else if (type == TYPE_OBJECT) {
                                    callback.success(message, com.alibaba.fastjson.JSON.parseObject(all.getString("result"), className));
                                }
                            } else {
                                //失败咯 然后传出去错误

                                if (TextUtils.isEmpty(message)) {
                                    message = "未知错误";
                                }
                                callback.fail(message);
                            }
                        } catch (Exception e) {
                            callback.fail("数据解析失败");
                        }
                    }
                });

            }
        });

    }

    public static String returnStr;


    public void post(final Activity activity, String url, HashMap<String, String> paramsMap, final Class className, final int type, final HttpCallback callback) {

        try {
            OkHttpClient client = new OkHttpClient.Builder().readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)//设置读取超时时间
                    .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)//设置写的超时时间
                    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)//设置连接超时时间;
                    .build();
            //处理参数

            FormBody.Builder builder = new FormBody.Builder();

            for (String key : paramsMap.keySet()) {
                if (paramsMap.get(key) != null)
                    builder.add(key, paramsMap.get(key));
            }
            RequestBody body = builder.build();
            Request request = new Request.Builder().post(body).url(url).build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, final IOException e) {
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            String s = e.getMessage();
                            callback.fail(s);
                        }
                    });

                }

                @Override
                public void onResponse(Call call, final Response response) throws IOException {
                    //Response{protocol=http/1.1, code=200, message=OK, url=http://yxsf.ynthgy.com/server//index.php/home/user/login}
                    returnStr = response.body().string();
                    returnStr = returnStr.replace("\"spec_goods_price\":null", "\"spec_goods_price\":\"\"");
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                JSONObject all = new JSONObject(returnStr);
                                String status = all.getString("status");
                                String message = all.getString("msg");
                                if (status.equals("1")) {
                                    if (type == TYPE_ARRAY) {
                                        callback.success(message, all.getJSONArray("result"));
                                    } else if (type == TYPE_NOTHING) {
                                        callback.success(message, all.getString("result"));
                                    } else if (type == TYPE_OBJECT) {
                                        callback.success(message, com.alibaba.fastjson.JSON.parseObject(all.getString("result"), className));
                                    }
                                } else {
                                    //失败咯 然后传出去错误
                                    if (TextUtils.isEmpty(message)) {
                                        message = "未知错误";
                                    }
                                    callback.fail(message);
                                }

                            } catch (Exception e) {
                                callback.fail("数据解析失败");
                            }
                        }
                    });
                }

            });
        } catch (Exception e) {
        }
    }

    public interface HttpCallback {
        public void success(String msg, Object json);

        public void fail(String failMsg);

    }


    private static void uploadImg(final Activity activity, String url, HashMap<String, String> LinkedHashMap, String picAddr, final HttpCallback callback) {

        // mImgUrls为存放图片的url集合
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS)//设置读取超时时间
                .writeTimeout(5, TimeUnit.SECONDS)//设置写的超时时间
                .connectTimeout(5, TimeUnit.SECONDS)//设置连接超时时间;
                .build();

        File f = new File(picAddr);
        if (f != null) {
            builder.addFormDataPart("avatar_file", f.getName(), RequestBody.create(MediaType.parse("image/*"), f));
        }

        Set<String> set = LinkedHashMap.keySet();
        for (String key : set) {
            builder.addFormDataPart(key, LinkedHashMap.get(key));
        }

        MultipartBody requestBody = builder.build();
        //构建请求
        Request request = new Request.Builder()
                .url(url)//地址
                .post(requestBody)//添加请求体
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        String s = e.getMessage();
                        callback.fail(s);
                    }
                });

            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                //Response{protocol=http/1.1, code=200, message=OK, url=http://yxsf.ynthgy.com/server//index.php/home/user/login}
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            String returnStr = response.body().string();
                            JSONObject all = new JSONObject(returnStr);
                            String status = all.getString("status");
                            String message = all.getString("msg");
                            if (status.equals("1")) {
                                callback.success(message, all.getString("result"));

                            } else {
                                callback.fail(message);
                            }
                        } catch (Exception e) {
                            callback.fail("数据解析失败");
                        }
                    }
                });
            }

        });
    }


    // 压缩图片并上传
    public static void uploadFileInThreadByOkHttp(final Activity activity, String url, HashMap<String, String> LinkedHashMap, List<PhotoInfo> resultList, final HttpCallback callback) {
        if (resultList.size() == 0) return;
        final String pic_path = resultList.get(0).getPhotoPath();
        String targetPath = Environment.getExternalStorageDirectory().getPath() + "/compressPic.jpg";
        //调用压缩图片的方法，返回压缩后的图片path
        final String compressImage = compressImage(pic_path, targetPath, 30);
        final File compressedPic = new File(compressImage);
        if (compressedPic.exists()) {
            uploadImg(activity, url, LinkedHashMap, targetPath, callback);
        } else {//直接上传
            uploadImg(activity, url, LinkedHashMap, targetPath, callback);
        }
    }


    public static String compressImage(String filePath, String targetPath, int quality) {
        Bitmap bm = compressByResolution(filePath);//获取一定尺寸的图片
        int degree = readPictureDegree(filePath);//获取相片拍摄角度
        if (degree != 0) {//旋转照片角度，防止头像横着显示
            bm = rotateBitmap(bm, degree);
        }
        File outputFile = new File(targetPath);
        try {
            if (!outputFile.exists()) {
                outputFile.getParentFile().mkdirs();
                //outputFile.createNewFile();
            } else {
                outputFile.delete();
            }
            FileOutputStream out = new FileOutputStream(outputFile);
            bm.compress(Bitmap.CompressFormat.JPEG, quality, out);
        } catch (Exception e) {
        }
        return outputFile.getPath();
    }

    /**
     * 根据路径获得图片信息并按比例压缩，返回bitmap
     */
    public static Bitmap getSmallBitmap(String filePath) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//只解析图片边沿，获取宽高
        BitmapFactory.decodeFile(filePath, options);
        // 计算缩放比
        options.inSampleSize = calculateInSampleSize(options, 1500, 800);
        // 完整解析图片返回bitmap
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }


    private static Bitmap compressByResolution(String imgPath) {

        BitmapFactory.Options opts1 = new BitmapFactory.Options();
        opts1.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imgPath, opts1);
        int height1 = opts1.outHeight;
        int width1 = opts1.outWidth;
        if (opts1.outWidth > 1500) {
            width1 = 1500;
            double scale = ((double) opts1.outWidth) / 1500d;
            height1 = (int) ((double) opts1.outHeight / scale);
        }


        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imgPath, opts);

        int width = opts.outWidth;
        int height = opts.outHeight;
        int widthScale = width / width1;
        int heightScale = height / height1;

        int scale;
        if (widthScale < heightScale) { //保留压缩比例小的
            scale = widthScale;
        } else {
            scale = heightScale;
        }

        if (scale < 1) {
            scale = 1;
        }
        Log.i(TAG, "图片分辨率压缩比例：" + scale);

        opts.inSampleSize = scale;

        opts.inJustDecodeBounds = false;

        Bitmap bitmap = BitmapFactory.decodeFile(imgPath, opts);

        return zoomImg(bitmap, width1, height1);
    }


    /**
     * 处理图片
     *
     * @param bm 所要转换的bitmap
     * @return 指定宽高的bitmap
     */
    public static Bitmap zoomImg(Bitmap bm, int newWidth, int newHeight) {
        // 获得图片的宽高
        int width = bm.getWidth();
        int height = bm.getHeight();
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片   www.2cto.com
        Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
        return newbm;
    }

    /**
     * 获取照片角度
     *
     * @param path
     * @return
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 旋转照片
     *
     * @param bitmap
     * @param degress
     * @return
     */
    public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {
        if (bitmap != null) {
            Matrix m = new Matrix();
            m.postRotate(degress);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), m, true);
            return bitmap;
        }
        return bitmap;
    }

    public static int calculateInSampleSize(BitmapFactory.Options options,
                                            int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }


}
